# -*- coding:utf-8 -*-
# -------------------------------------------------------------------------------
# Description:  
# Reference:
# Author: 安智军
# Date:   2021/11/17
# -------------------------------------------------------------------------------
import datetime
import json
import time
import allure
import yaml
from selenium.webdriver.support.wait import WebDriverWait

from config import basepath
from Common.GetDriver import GetLog
from Common.GetDriver import GetDriver
from Common.load_json import read_cookie_txt, read_sessionStorage_dict
from PageLocators.PageLoginLoc import LoginPageLoc as loc
log = GetLog.get_logger()


class Base:
    """
    封装常用的方法
    """

    def __init__(self, driver):
        self.driver = driver  # 初始化driver

    # 使用显式等待，持续查找5s,每0.5s查找一次
    def base_find_element(self, location, timeout=5, poll_frequency=0.5):
        '''
        查找元素的方法
        :param location:元素定位信息
        :param timeout: 最长查找时间
        :param poll_frequency: 查找频率
        :return:返回查找到的元素
        '''
        return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll_frequency).until(
            lambda x: x.find_element(*location))

    # 确定查找的元素是否存在的方法
    def base_element_if_exists(self, location):
        '''
        确定元素是否存在的方法
        :param location: 元素你定位信息
        :return: 返回布尔值 True存在 False不存在
        '''
        log.info("正在查找 %s 元素" % str(location))
        try:  # try一下捕获异常
            start = datetime.datetime.now()
            self.base_find_element(location, timeout=5)
            end = datetime.datetime.now()
            log.info("已找到 {} 元素,等待{}秒" .format(str(location),(end-start).seconds))
            return True
        except:  # 没找到元素走这里
            log.error("未找到： %s 元素" % str(location))
            return False

    # 点击方法
    def base_click(self, location):
        '''
        点击方法（点击前要判断元素是否存在）
        :param location: 元素定位信息 比如xpath定位、css定位
        :return: 无返回值
        '''
        # 先判断需要点击的元素是否存在，存在了在进行点击操作
        if self.base_element_if_exists(location):  # 相当于 if xxx==True
            log.info("正在点击: %s 元素" % str(location))
            self.base_find_element(location).click()

        # hamburger_class_name = "class"
        # # 先判断需要点击的元素是否存在，存在了在进行点击操作
        # if self.base_element_if_exists(location):  # 相当于 if xxx==True
        #     log.info("正在点击: %s 元素" % str(location))
        #     if self.base_get_element_attribute_value(location,hamburger_class_name) == "hamburger": # 说明菜单未展开
        #         log.info("菜单未展开，正在点击展开")
        #         self.base_click(location)
        #     else:
        #         self.base_find_element(location).click()



    # 清空的方法
    def base_clear(self, location):
        '''
        对输入的内容进行清空处理
        :param location: 元素的定位信息
        :return:
        '''
        if self.base_element_if_exists(location):
            log.info("正在对：%s 元素执行清空操作" % str(location))
            self.base_find_element(location).clear()

    # 找到输入框输入内容
    def base_input(self, location, text):
        '''
        输入方法
        :param location: 元素的定位信息
        :param text: 输入的内容
        :return:
        '''
        # 先清空元素，在进行输入
        self.base_clear(location)
        log.info("%s 元素已清空" % str(location))
        log.info("正在对元素:%s 执行输入操作" % str(location))
        self.base_find_element(location).send_keys(text)

    def base_get_screenshot(self):
        '''
        截图方法，用来记录异常
        :return:
        '''
        log.info("执行过程中发现错误，正在截图，记录异常信息")
        time.sleep(1)
        # 生成html报告用下面这个
        # self.driver.get_screenshot_as_file("./screenshots/" + time.strftime("%Y-%m-%d-%H-%M-%S") + ".png")

        # 生成allure报告用下面这个
        self.driver.get_screenshot_as_file(basepath + "/Outputs/screenshots/error.png")
        time.sleep(1)

        self.__base_write_screenshot()

    # 将获取到的异常截图写入allure报告中
    def __base_write_screenshot(self):
        '''
        将获取到的异常截图写入allure报告中
        :return:
        '''
        # 获取图片文件流
        with open(basepath + "/Outputs/screenshots/error.png", "rb") as f:
            allure.attach(f.read(), "失败截图：", allure.attachment_type.PNG)  # 这样写才能把错误截图写入到allure报告中！！！

    def base_switch_to_frame(self, location):
        '''
        切换表单方法
        :param location: 元素定位信息
        :return:
        '''
        if self.base_find_element(location):
            log.info("正在进行切换表单操作，要切换的表单元素为  %s  " % str(location))
            element = self.base_find_element(location)
            self.driver.switch_to.frame(element)
            log.info("表单切换成功")

    def base_switch_to_default_content(self):
        '''
        切换到默认表单方法
        :return:
        '''
        log.info("正在切换到默认表单")
        self.driver.switch_to.default_content()
        log.info("表单切换成功")

    def base_switch_to_window(self, num):
        '''
        切换浏览器窗口方法
        :param num: 要切换窗口的索引（0是默认窗口）
        :return:
        '''
        log.info("正在切换浏览器窗口")
        handles = self.driver.window_handles
        self.driver.switch_to.window(handles[num])
        log.info("窗口切换成功")

    def base_get_element_text(self, location):
        '''
        获取指定元素的文本内容方法
        :param location: 元素定位信息
        :return: 返回获取指定元素的文本信息
        '''
        if self.base_element_if_exists(location):
            log.info("正在获取  %s  元素的文本内容" % str(location))
            return self.base_find_element(location).text

    def base_get_element_attribute_value(self, location, Element_attribute_name):
        '''
        通过元素定位定位到该元素并且通过元素名称获取到指定元素的值 用于判断菜单按钮是否展开
        :param location: 元素的位置
        :param Element_attribute_name: 元素名称
        :return: 元素名称的值
        '''
        log.info("正在查找: %s 元素" % str(location))
        try:
            element = self.base_find_element(location, timeout=2)
            log.info("已找到 %s 元素" % str(location))
            # 获取元素中指定名称的值
            element_attribute_value = element.get_attribute("%s" % Element_attribute_name)  # 元素属性值
            return element_attribute_value
        except:
            log.info("未找到 %s 元素，无法获取到该元素的值" % str(location))

    def base_click_hamber_btn(self,location):
        '''
        通过获取菜单按钮的值判断菜单按钮是否已展示
        :param location: 菜单按钮的定位
        :return:
        '''
        hamburger_class_name = "class"
        if self.base_get_element_attribute_value(location,hamburger_class_name) == "hamburger": # 说明菜单未展开
            log.info("菜单未展开，正在点击展开")
            self.base_click(location)
        else:
            log.info("当前菜单已展开，无需展开,继续执行下一步操作")



        element = self.base_find_element(location, timeout=2)
        log.info("已找到 %s 元素" % str(location))
        # 获取元素中指定名称的值
        element_attribute_value = element.get_attribute("class" )  # 元素属性值


    def base_get_sessionStorage(self, driver):
        '''
        通过登录成功后的driver获取到sessionStorage的所有值并组成字典写入sessionStorage中
        :param driver:
        :return:
        '''
        token = driver.execute_script('return sessionStorage.getItem("token");')
        userInfo = driver.execute_script('return sessionStorage.getItem("userInfo");')
        systemType = driver.execute_script('return sessionStorage.getItem("systemType");')
        asyncRoutes = driver.execute_script('return sessionStorage.getItem("asyncRoutes");')
        currWarehouse = driver.execute_script('return sessionStorage.getItem("currWarehouse");')
        orderType = driver.execute_script('return sessionStorage.getItem("orderType");')
        cityData = driver.execute_script('return sessionStorage.getItem("cityData");')
        isManageRoutes = driver.execute_script('return sessionStorage.getItem("isManageRoutes");')
        sessionStorage_dict = {"token": "%s" % token, "userInfo": "%s" % userInfo, "systemType": "%s" % systemType,
                               "asyncRoutes": "%s" % asyncRoutes,
                               "currWarehouse": "%s" % currWarehouse, "orderType": "%s" % orderType,
                               "cityData": "%s" % cityData,"isManageRoutes": "%s" % isManageRoutes}
        # 将sessionStorage值保存到sessionStorage.txt文件,以字典保存
        with open(basepath+r"\TestDatas\ssessionStorage.txt", "w+") as f:
            f.write(json.dumps(sessionStorage_dict))

    def base_save_cookies(self, driver):
        cookies = driver.get_cookies()
        print("获取到的cookies为:", cookies)
        with open(basepath+r"\TestDatas\cookie.txt", "w+") as f:
            f.write(json.dumps(cookies))
        return cookies

    def base_use_Secret_free_login_method(self):
        '''
        免密登录的方法 免账号密码登录
        :return:
        '''
        # 获取登录接口地址
        driver = GetDriver.get_web_Chrome_driver(loc.url_login)
        driver.implicitly_wait(30)

        # # 从cookie.txt文件中获取cookies并添加到cookies中
        # cookies_dict = read_cookie_txt()
        # driver.add_cookie(cookies_dict)

        #  从sessionStorage.txt文件中获取每个值并添加到sessionStorage中
        sessionStorage_dict = read_sessionStorage_dict()

        orderType = sessionStorage_dict["orderType"]
        js = 'sessionStorage.setItem("orderType",JSON.stringify({0}))'.format(orderType)
        driver.execute_script(js)

        userInfo = sessionStorage_dict["userInfo"]
        js = 'window.sessionStorage.setItem("userInfo",JSON.stringify({0}))'.format(userInfo)
        driver.execute_script(js)

        asyncRoutes = sessionStorage_dict["asyncRoutes"]
        js = 'sessionStorage.setItem("asyncRoutes",JSON.stringify({0}))'.format(asyncRoutes)
        driver.execute_script(js)

        cityData = sessionStorage_dict["cityData"]
        js = 'window.sessionStorage.setItem("cityData",JSON.stringify({0}))'.format(cityData)
        driver.execute_script(js)

        currWarehouse = sessionStorage_dict["currWarehouse"]
        js = 'window.sessionStorage.setItem("currWarehouse",JSON.stringify({0}))'.format(currWarehouse)
        driver.execute_script(js)

        systemType = sessionStorage_dict["systemType"]
        js = 'sessionStorage.setItem("systemType","{0}")'.format(systemType)
        driver.execute_script(js)

        token = sessionStorage_dict["token"]
        js = 'sessionStorage.setItem("token","{0}")'.format(token)
        driver.execute_script(js)

        isManageRoutes = sessionStorage_dict["isManageRoutes"]
        js = 'sessionStorage.setItem("isManageRoutes","{0}")'.format(isManageRoutes)
        driver.execute_script(js)

        time.sleep(1)

        driver.refresh()
        time.sleep(1)
        return driver






